home *** CD-ROM | disk | FTP | other *** search
- /* Support code from Micro Cornucopia Magazine Issue #48
-
- Micro Cornucopia
- PO Box 223
- Bend, OR 97709 */
-
- #include <io.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <dir.h>
- #include <time.h> /* to calculate transfer speeds */
- #include "ppxfer.h" /* header file containing appropriate definitions */
-
- dbyte base_plus_two; /* global so output value at BASE+2 doesn't accidentally
- get changed */
- #define RAISE_HANDSHAKE (outportb(BASE+2, base_plus_two &= ~(1 << 3)))
- #define LOWER_HANDSHAKE (outportb(BASE+2, base_plus_two |= (1 << 3)))
-
- #define TESTKEY if (kbhit()) break
-
- /* Prints a byte in binary (for testing): */
- void print_binary(dbyte c) {
- int i = 7;
- do printf("%c", c & (1 << i) ? '1' : '0'); while(i--);
- }
-
- /* Set the channel to the "idle" state: */
- void idle(void) {
- outportb(BASE,0xff); /* all lines high */
- /* initialize so everything's an input (handshake is high): */
- outportb(BASE+2, (base_plus_two = 0x04));
- }
-
- dbyte receive_byte(void) {
- dbyte data;
- while( ! (inportb(BASE+2) & (1<<3)))
- ;
- data = (inportb(BASE+1) & 0xf8) | (inportb(BASE+2) & 0x07);
- outportb(BASE, 0xfe); /* send BYTE RECD signal */
- data ^= 0x83; /* flip "inverted" bits */
- while( (inportb(BASE+2) & (1<<3)))
- ;
- outportb(BASE, 0xff); /* de-assert BYTE RECD signal */
- return data;
- }
-
- void send_byte( dbyte data) {
- outportb(BASE, data);
- LOWER_HANDSHAKE;
- while( ! (inportb(BASE+2) & 1)) {
- if (inportb(BASE+2) & 2) {
- puts("aborted by receiver");
- exit(1);
- }
- TESTKEY;
- }
- RAISE_HANDSHAKE;
- while ( inportb(BASE + 2) & 1) {
- if (inportb(BASE+2) & 2) { puts("aborted"); exit(1); }
- TESTKEY;
- }
- }
-
- void send_string( char * string) {
- while(*string) {
- send_byte(*string);
- string++;
- }
- }
-
- void usage(char * msg) {
- puts("\nusage: ppxfer -s file1.ext ...");
- puts(" to send files through the parallel port using the special");
- puts(" cable configuration, (the list of files can be any length;");
- puts(" wildcards may be used in the file name) or:");
- puts("ppxfer -sh file1.ext ...");
- puts(" to send files and leave the receiver on hold so other");
- puts(" files may be sent, or:");
- puts("ppxfer -r");
- puts(" to receive files.");
- puts(msg);
- exit(1);
- }
-
- void send_file(char * unambiguous_name) {
- int i, infile;
- unsigned long filesize, readsize;
- char buf[30];
- dbyte filebuf[BUFSIZE];
- long secs_start, secs_end; /* for timing */
-
- if ((infile = open(unambiguous_name,O_RDONLY | O_BINARY )) < 0 ) {
- puts("cannot open file to send:");
- puts(unambiguous_name);
- exit(1);
- }
- filesize = lseek(infile, 0L, 2); /* find file size */
- lseek(infile, 0L, 0); /* reset file pointer to beginning */
- ultoa(filesize,buf,10);
- idle();
- send_byte(ATTN); /* send an escape */
- send_string("filename"); send_byte(LDELIMIT);
- send_string(unambiguous_name); send_byte(RDELIMIT);
- send_byte(LDELIMIT);
- send_string(buf); send_byte(RDELIMIT);
- printf("sending %-15s size: %s bytes: ", unambiguous_name, buf);
- #ifdef TIME
- time(&secs_start);
- printf("starting time: %d\n", secs_start);
- #endif TIME
- while((readsize = read(infile, filebuf, BUFSIZE)) > 0 )
- #ifdef MASM
- send_block(filebuf, readsize);
- #else MASM /* if you don't have MASM, you'll have to do it the slow way: */
- for (i = 0; i < readsize; i++)
- send_byte(filebuf[i]);
- #endif MASM
- close(infile);
- #ifdef TIME
- time(&secs_end);
- printf("ending time: %d\n", secs_end);
- printf("%f Kbytes/sec\n", (filesize/1000)/(secs_end - secs_start));
- #endif TIME
- }
-
- void receive_files(void) {
- char c;
- int i,j, outfile;
- unsigned long incr, filesize, bytecount, readsize;
- char buf[30], filename[30];
- dbyte filebuf[BUFSIZE];
-
- idle();
- while(1) {
- while ( receive_byte() != ATTN )
- if (kbhit()) if (getch() == 27) exit(1);
- /* hunt for an ESCAPE from the port or the keyboard */
- for (i=0; (c = receive_byte()) != LDELIMIT; )
- buf[i++] = c;
- buf[i] = 0; /* end of control string */
- if (strcmp(buf,"end of transaction") == 0) {
- puts("end of transaction");
- exit(0);
- }
- if (strcmp(buf,"filename") == 0) {
- for (i=0; (c = receive_byte()) != RDELIMIT; )
- filename[i++] = c;
- filename[i] = 0;
- for (i=0; (c = receive_byte()) != LDELIMIT; )
- ; /* throw away characters until left delimiter */
- for (i=0; (c = receive_byte()) != RDELIMIT; )
- buf[i++] = c; /* store characters until right delimiter */
- buf[i] = 0;
- filesize = atol(buf);
- printf("receiving %-15s size: %s bytes\n",filename, buf);
- if ((outfile = open(filename,
- O_WRONLY | O_BINARY | O_CREAT, S_IREAD|S_IWRITE)) < 0 ) {
- puts("cannot open output file");
- outportb(BASE,0xfd); /* set "abort" line */
- switch(errno) {
- case ENOENT: puts("path or file name not found"); break;
- case EMFILE: puts ("too many open files"); break;
- case EACCES: puts ("permission denied"); break;
- case EINVACC: puts("invalid access code");
- }
- exit(1);
- }
- for (incr = (signed)(filesize - BUFSIZE) > 0 ?
- BUFSIZE : filesize, bytecount = 0;
- bytecount < filesize;
- bytecount += incr,
- incr = filesize - bytecount > BUFSIZE ? BUFSIZE
- : filesize - bytecount ) {
- receive_block(filebuf,incr);
- write(outfile, filebuf, incr);
- }
- close(outfile);
- }
- }
- }
-
- void main(int argc, char * argv[]) {
- struct ffblk file_block;
- int i, done;
-
- if (argv[1][0] != '-' ||
- (argv[1][1] != 's' && argv[1][1] != 'r')) usage("use '-s' or '-r'");
-
- /* receive files: */
- if (argv[1][1] == 'r')
- receive_files();
-
- /* send files using wildcards: */
- if (argv[1][1] == 's' ) {
- if (argc < 3) usage("not enough arguments");
- for(i = 2; i < argc; i++) {
- done = findfirst(argv[i],&file_block,0);
- while (!done) {
- send_file(file_block.ff_name);
- done = findnext(&file_block);
- }
- }
- if (argv[1][2] == 'h')
- { puts("receiver ready for more files"); exit(0); }
- send_byte(ATTN);
- send_string("end of transaction"); send_byte(LDELIMIT);
- }
- }